home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Pascal / Games / Glypha 3.02 / source / Code ƒ / D-GameUtils.p < prev    next >
Encoding:
Text File  |  1993-06-03  |  29.2 KB  |  948 lines  |  [TEXT/PJMM]

  1. unit GameUtils;
  2.  
  3. interface
  4.  
  5.     uses
  6.         Dialogs, Sound;
  7.  
  8.     const
  9.         liftAmount = -8;
  10.         fallAmount = 1;
  11.         maxFall = 10;
  12.         maxThrust = 16;
  13.         defaultNum = 4;
  14.  
  15.         upperLevel = 0;
  16.         lowerLevel = 1;
  17.         upperEye = 2;
  18.         lowerEye = 3;
  19.  
  20.         fastest = 0;
  21.         fast = 1;
  22.         slow = 3;
  23.         slowest = 4;
  24.  
  25.         source = 0;
  26.         mask = 1;
  27.  
  28.     type
  29.         GameObject = record
  30.                 oldDest, dest, wholeRect: Rect;
  31.                 horiVel, vertVel: Integer;
  32.                 facing: Integer;
  33.                 mode, otherMode, tempInt: Integer;
  34.                 state, otherState: Boolean;
  35.             end;
  36.  
  37.         Bolt = record
  38.                 levelStriking: Integer;
  39.                 leftMode, rightMode: Integer;
  40.                 leftBolts, rightBolts: array[0..3, 0..3, 0..11] of Point;
  41.             end;
  42.  
  43.     var
  44.         {Here follow all the major global variables                            }
  45.         {(yes, there are quite a few)                                                        }
  46.         {Here are then menu handles                                                            }
  47.         AppleMenu, GameMenu, OptionsMenu: MenuHandle;
  48.  
  49.         {The boolean vars often keep track of the game state        }
  50.         playing, pausing, keyboardControl, soundOn, onFastMachine: Boolean;
  51.         deadAndGone, scoresChanged, inhibitSound, doneFlag: Boolean;
  52.         onward, keyStillDown, stonesSliding: Boolean;
  53.  
  54.         {Integers keep track of numbers, level, modes, etc...        }
  55.         numberOfStones, levelOn, mortals, oldDirection: Integer;
  56.         beastsKilled, beastsActive, totalToKill, levelStart, mortalsStart: Integer;
  57.         delayFor, startStone, playMask, growRate, numberOfEnemies: Integer;
  58.  
  59.         {Score is LongInt for the 12 yr old kids that top    36727    }
  60.         gameCycle, score, oldScore, nextMortal, lastLoopTime: LongInt;
  61.  
  62.         {Keep track of the name last entered for the high score    }
  63.         nameUsing: Str255;
  64.  
  65.         {And the ahnk (SP?) cursor variable                                            }
  66.         ahnkCursor: CursHandle;
  67.  
  68.         {Here follow the offscreen bitmap and window variables    }
  69.         mainWndo: WindowPtr;
  70.         playRgn, obeliskRgn1, obeliskRgn2: RgnHandle;
  71.         offEnemyArea, offVirginArea, offLoadArea, offPlayerArea: Rect;
  72.         offEnemyMap, offVirginMap, offLoadMap, offPlayerMap: BitMap;
  73.         offEnemyPort, offVirginPort, offLoadPort, offPlayerPort: GrafPtr;
  74.         offEnemyBits, offVirginBits, offLoadBits, offPlayerBits: Ptr;
  75.  
  76.         {Here are some of the object definition records                    }
  77.         theEye, theHand, thePlayer: GameObject;
  78.         lightning: Bolt;
  79.  
  80.         {Miscellaneous rects for the score box, platforms, etc..}
  81.         scoreGrabRect, scoreDropRect, littleTombRect, playRect: Rect;
  82.         upperTombRect1, upperTombRect2: Rect;
  83.  
  84.         {For the digitized sound                                                                }
  85.         chanPtr: sndchannelptr;
  86.  
  87.         {Arrays hold hiscores made and read from .RSRC fork            }
  88.         hiScores: array[1..10] of LongInt;
  89.         hiStrings: array[1..10] of Str255;
  90.  
  91.         {These vars hold info on the enemies                                        }
  92.         theEnemies: array[0..9] of GameObject;
  93.         enemyLift: array[0..2] of Integer;
  94.  
  95.         {These vars hold locations of all artwork on offscreens    }
  96.         tombRects: array[-5..6] of Rect;
  97.         playerRects: array[0..3, 0..5] of Rect;
  98.         enemyRects: array[0..2, 0..5, 0..1, 0..1] of Rect;
  99.         boneRects: array[0..1, 6..7, 0..1] of Rect;
  100.         absoluteRects: array[0..1, 0..5] of Rect;
  101.         eyeRects: array[0..9] of Rect;
  102.         handRects: array[0..1, 0..1] of Rect;
  103.         ankRects: array[0..15, 0..1] of Rect;
  104.         eggRects, gameoverRects, flameRect: array[0..1] of Rect;
  105.         running: array[-16..16, 0..1, 0..1] of Integer;
  106.         idleLanded: array[-16..16] of Integer;
  107.         gliding: array[-16..16, 0..1] of Integer;
  108.         impacted: array[-70..16] of Integer;
  109.  
  110.     procedure NewLightning;
  111.     procedure StrikeLightning (whichLevel: Integer);
  112.     procedure DoTheSound (whichOne: Str255; asynch: Boolean);
  113.     function DoRandom (range: Integer): Integer;
  114.     procedure ChangeRect;
  115.     procedure DrawPlayer (newRect, oldRect: Rect);
  116.     procedure DrawBeasts;
  117.     procedure DrawHand;
  118.     procedure RedoTheBackground;
  119.     procedure ShowScore;
  120.     procedure DoTheHoopla;
  121.     procedure CheckExtraMortal;
  122.     procedure ReDrawHiScores;
  123.     procedure ReadInScores;
  124.     procedure WriteOutScores;
  125.     procedure FinalScore;
  126.     procedure DoHelpScreen;
  127.     procedure FlushTheScores;
  128.  
  129. {=================================}
  130.  
  131. implementation
  132.  
  133. {=================================}
  134.  
  135.     procedure NewLightning;
  136.         const
  137.             upperHeight = 125;
  138.             lowerHeight = 296;
  139.             upperEyeHeight = 75;
  140.             lowerEyeHeight = 175;
  141.             upperDelta = upperHeight - 141;
  142.             lowerDelta = lowerHeight - 141;
  143.             upperEyeDelta = upperEyeHeight - 141;
  144.             lowerEyeDelta = lowerEyeHeight - 141;
  145.             pylonToCenter = 124;
  146.         var
  147.             index, index2, travel, hori, vert: Integer;
  148.     begin
  149.         with lightning do
  150.             begin
  151.                 levelStriking := upperLevel;
  152.                 leftMode := DoRandom(4);
  153.                 rightMode := DoRandom(4);
  154.                 for index := 0 to 3 do
  155.                     begin
  156.                         SetPt(leftBolts[upperLevel, index, 0], 132, 141);
  157.                         SetPt(rightBolts[upperLevel, index, 0], 378, 141);
  158.                         SetPt(leftBolts[lowerLevel, index, 0], 132, 141);
  159.                         SetPt(rightBolts[lowerLevel, index, 0], 378, 141);
  160.                         SetPt(leftBolts[upperEye, index, 0], 132, 141);
  161.                         SetPt(rightBolts[upperEye, index, 0], 378, 141);
  162.                         SetPt(leftBolts[lowerEye, index, 0], 132, 141);
  163.                         SetPt(rightBolts[lowerEye, index, 0], 378, 141);
  164.                     end;
  165.                 for index := 0 to 3 do
  166.                     for index2 := 1 to 10 do
  167.                         begin
  168.                             travel := (6 - ABS(index2 - 6)) * 5;
  169.                             hori := 132 + (index2 * (pylonToCenter div 12));
  170.                             vert := 141 + (index2 * (upperDelta div 12));
  171.                             vert := vert + DoRandom(travel * 2) - travel;
  172.                             SetPt(leftBolts[upperLevel, index, index2], hori, vert);
  173.                             hori := 380 - (index2 * (pylonToCenter div 12));
  174.                             vert := 141 + (index2 * (upperDelta div 12));
  175.                             vert := vert + DoRandom(travel * 2) - travel;
  176.                             SetPt(rightBolts[upperLevel, index, index2], hori, vert);
  177.                             hori := 132 + (index2 * (pylonToCenter div 12));
  178.                             vert := 141 + (index2 * (lowerDelta div 12));
  179.                             vert := vert + DoRandom(travel * 2) - travel;
  180.                             SetPt(leftBolts[lowerLevel, index, index2], hori, vert);
  181.                             hori := 380 - (index2 * (pylonToCenter div 12));
  182.                             vert := 141 + (index2 * (lowerDelta div 12));
  183.                             vert := vert + DoRandom(travel * 2) - travel;
  184.                             SetPt(rightBolts[lowerLevel, index, index2], hori, vert);
  185.  
  186.                             hori := 132 + (index2 * (pylonToCenter div 12));
  187.                             vert := 141 + (index2 * (upperEyeDelta div 12));
  188.                             vert := vert + DoRandom(travel * 2) - travel;
  189.                             SetPt(leftBolts[upperEye, index, index2], hori, vert);
  190.                             hori := 380 - (index2 * (pylonToCenter div 12));
  191.                             vert := 141 + (index2 * (upperEyeDelta div 12));
  192.                             vert := vert + DoRandom(travel * 2) - travel;
  193.                             SetPt(rightBolts[upperEye, index, index2], hori, vert);
  194.                             hori := 132 + (index2 * (pylonToCenter div 12));
  195.                             vert := 141 + (index2 * (lowerEyeDelta div 12));
  196.                             vert := vert + DoRandom(travel * 2) - travel;
  197.                             SetPt(leftBolts[lowerEye, index, index2], hori, vert);
  198.                             hori := 380 - (index2 * (pylonToCenter div 12));
  199.                             vert := 141 + (index2 * (lowerEyeDelta div 12));
  200.                             vert := vert + DoRandom(travel * 2) - travel;
  201.                             SetPt(rightBolts[lowerEye, index, index2], hori, vert);
  202.                         end;
  203.                 for index := 0 to 3 do
  204.                     begin
  205.                         SetPt(leftBolts[upperLevel, index, 11], 256, upperHeight);
  206.                         SetPt(rightBolts[upperLevel, index, 11], 254, upperHeight);
  207.                         SetPt(leftBolts[lowerLevel, index, 11], 256, lowerHeight);
  208.                         SetPt(rightBolts[lowerLevel, index, 11], 254, lowerHeight);
  209.                         SetPt(leftBolts[upperEye, index, 11], 256, upperEyeHeight);
  210.                         SetPt(rightBolts[upperEye, index, 11], 254, upperEyeHeight);
  211.                         SetPt(leftBolts[lowerEye, index, 11], 256, lowerEyeHeight);
  212.                         SetPt(rightBolts[lowerEye, index, 11], 254, lowerEyeHeight);
  213.                     end;
  214.             end;
  215.     end;
  216.  
  217. {=================================}
  218.  
  219.     procedure StrikeLightning;
  220.         var
  221.             index: Integer;
  222.             isPoint, wasPoint: Point;
  223.             savedPort: GrafPtr;
  224.     begin
  225.         GetPort(savedPort);
  226.         SetPort(mainWndo);
  227.         InvertRgn(obeliskRgn1);
  228.         InvertRgn(obeliskRgn2);
  229.         PenNormal;
  230.         PenSize(2, 2);
  231.         PenMode(patXOr);
  232.         with lightning do
  233.             begin
  234.                 leftMode := DoRandom(4);
  235.                 rightMode := DoRandom(4);
  236.                 for index := 1 to 11 do
  237.                     begin
  238.                         isPoint := leftBolts[whichLevel, leftMode, index];
  239.                         wasPoint := leftBolts[whichLevel, leftMode, index - 1];
  240.                         MoveTo(wasPoint.h, wasPoint.v);
  241.                         LineTo(isPoint.h - 2, isPoint.v);
  242.                         isPoint := rightBolts[whichLevel, leftMode, index];
  243.                         wasPoint := rightBolts[whichLevel, leftMode, index - 1];
  244.                         MoveTo(wasPoint.h, wasPoint.v);
  245.                         LineTo(isPoint.h + 2, isPoint.v);
  246.                     end;
  247.                 for index := 1 to 11 do
  248.                     begin
  249.                         isPoint := leftBolts[whichLevel, leftMode, index];
  250.                         wasPoint := leftBolts[whichLevel, leftMode, index - 1];
  251.                         MoveTo(wasPoint.h, wasPoint.v);
  252.                         LineTo(isPoint.h - 2, isPoint.v);
  253.                         isPoint := rightBolts[whichLevel, leftMode, index];
  254.                         wasPoint := rightBolts[whichLevel, leftMode, index - 1];
  255.                         MoveTo(wasPoint.h, wasPoint.v);
  256.                         LineTo(isPoint.h + 2, isPoint.v);
  257.                     end;
  258.             end;
  259.         InvertRgn(obeliskRgn1);
  260.         InvertRgn(obeliskRgn2);
  261.         SetPort(savedPort);
  262.     end;
  263.  
  264. {=================================}
  265.  
  266.     procedure DoTheSound;
  267.         var
  268.             theSnd: Handle;
  269.             err: OSErr;
  270.     begin
  271.         if (soundOn) then
  272.             begin
  273.                 theSnd := GetNamedResource('snd ', whichOne);
  274.                 if (theSnd <> nil) and (ResError = noErr) then
  275.                     begin
  276.                         if (chanPtr <> nil) then
  277.                             begin
  278.                                 err := SndDisposeChannel(chanPtr, TRUE);
  279.                                 chanPtr := nil;
  280.                             end;
  281.                         if (asynch = true) and (SndNewChannel(chanPtr, 0, initMono, nil) = noErr) then
  282.                             err := SndPlay(chanPtr, theSnd, TRUE)
  283.                         else
  284.                             err := SndPlay(nil, theSnd, FALSE);
  285.                     end;
  286.             end;
  287.     end;
  288.  
  289. {=================================}
  290.  
  291.     function DoRandom;
  292.         var
  293.             rawResult: LongInt;
  294.     begin
  295.         rawResult := Abs(Random);
  296.         DoRandom := (rawResult * range) div 32768
  297.     end;
  298.  
  299. {=================================}
  300.  
  301.     procedure ChangeRect;
  302.         var
  303.             hori, vert: Integer;
  304.     begin
  305.         with thePlayer do
  306.             begin
  307.                 hori := dest.left;
  308.                 vert := dest.top;
  309.                 if (mode < 6) then
  310.                     dest := absoluteRects[facing, mode]
  311.                 else
  312.                     begin
  313.                         SetRect(dest, 0, 0, 44, 23);
  314.                         dest.top := dest.top + 15;
  315.                         dest.bottom := dest.bottom + 15;
  316.                     end;
  317.                 dest.left := dest.left + hori;
  318.                 dest.right := dest.right + hori;
  319.                 dest.top := dest.top + vert;
  320.                 dest.bottom := dest.bottom + vert;
  321.             end;
  322.     end;
  323.  
  324. {=================================}
  325.  
  326.     procedure DrawPlayer;
  327.         var
  328.             index, hori, vert: integer;
  329.             dummyLong: LongInt;
  330.             standInRect, standInRect2, tempRect: Rect;
  331.     begin
  332.         with thePlayer do
  333.             case mode of
  334.                 0..5: 
  335.                     begin
  336.                         UnionRect(oldRect, newRect, wholeRect);
  337.                         CopyBits(offVirginMap, offLoadMap, wholeRect, wholeRect, srcCopy, nil);
  338.                         CopyMask(offPlayerMap, offPlayerMap, offLoadMap, playerRects[facing, mode], playerRects[facing + 2, mode], newRect);
  339.                         CopyBits(offLoadMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, playRgn);
  340.                         if (otherState) then
  341.                             begin
  342.                                 mode := 6;
  343.                                 CopyBits(offVirginMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, playRgn);
  344.                                 hori := newRect.left;
  345.                                 vert := newRect.top;
  346.                                 SetRect(newRect, 0, 0, 48, 38);
  347.                                 tempRect := newRect;
  348.                                 newRect.left := newRect.left + hori;
  349.                                 newRect.right := newRect.right + hori;
  350.                                 newRect.top := newRect.top + vert;
  351.                                 newRect.bottom := newRect.bottom + vert;
  352.                                 dest := newRect;
  353.                                 tempRect.left := tempRect.left + 232;
  354.                                 tempRect.right := tempRect.right + 232;
  355.                                 tempRect.top := tempRect.top + 306;
  356.                                 tempRect.bottom := tempRect.bottom + 306;
  357.                                 SetPort(offLoadPort);
  358.                                 for index := 1 to 10 do
  359.                                     begin
  360.                                         EraseRect(tempRect);
  361.                                         CopyBits(offVirginMap, offLoadMap, newRect, tempRect, srcCopy, nil);
  362.                                         CopyMask(offLoadMap, offPlayerMap, offLoadMap, tempRect, boneRects[facing, mode, 1], newRect);
  363.                                         CopyBits(offLoadMap, mainWndo^.portBits, newRect, newRect, srcCopy, playRgn);
  364.                                         Delay(1, dummyLong);
  365.                                         CopyBits(offVirginMap, offLoadMap, newRect, newRect, srcCopy, nil);
  366.                                         CopyMask(offPlayerMap, offPlayerMap, offLoadMap, boneRects[facing, mode, 0], boneRects[facing, mode, 1], newRect);
  367.                                         CopyBits(offLoadMap, mainWndo^.portBits, newRect, newRect, srcCopy, playRgn);
  368.                                     end;
  369.                                 CopyBits(offVirginMap, mainWndo^.portBits, newRect, newRect, srcCopy, playRgn);
  370.                             end;
  371.                     end;
  372.                 6: 
  373.                     begin
  374.                         UnionRect(oldRect, newRect, wholeRect);
  375.                         CopyBits(offVirginMap, offLoadMap, wholeRect, wholeRect, srcCopy, nil);
  376.                         CopyMask(offPlayerMap, offPlayerMap, offLoadMap, boneRects[facing, mode, 0], boneRects[facing, mode, 1], newRect);
  377.                         CopyBits(offLoadMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, playRgn);
  378.                     end;
  379.                 7..100: 
  380.                     begin
  381.                         UnionRect(oldRect, newRect, wholeRect);
  382.                         CopyBits(offVirginMap, offLoadMap, wholeRect, wholeRect, srcCopy, nil);
  383.                         standInRect := boneRects[facing, 7, 0];
  384.                         standInRect2 := boneRects[facing, 7, 1];
  385.                         vert := dest.bottom - dest.top;
  386.                         standInRect.bottom := standInRect.top + vert;
  387.                         standInRect2.bottom := standInRect2.top + vert;
  388.                         CopyMask(offPlayerMap, offPlayerMap, offLoadMap, standInRect, standInRect2, newRect);
  389.                         CopyBits(offLoadMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, playRgn);
  390.                     end;
  391.                 otherwise
  392.                     begin
  393.                     end;
  394.             end;
  395.     end;
  396.  
  397. {=================================}
  398.  
  399.     procedure DrawHand;
  400.     begin
  401.         with theHand do
  402.             begin
  403.                 UnionRect(oldDest, dest, wholeRect);
  404.                 CopyBits(offVirginMap, offLoadMap, wholeRect, wholeRect, srcCopy, nil);
  405.                 CopyMask(offPlayerMap, offPlayerMap, offLoadMap, handRects[mode, source], handRects[mode, mask], dest);
  406.                 CopyBits(offLoadMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, playRgn);
  407.             end;
  408.     end;
  409.  
  410. {=================================}
  411.  
  412.     procedure DrawBeasts;
  413.         var
  414.             index: Integer;
  415.             otherRect, otherMask, tempSrc, tempMask: Rect;
  416.     begin
  417. {swap flames on background}
  418.         CopyBits(offVirginMap, offLoadMap, flameRect[0], flameRect[0], srcCopy, nil);
  419.         CopyBits(offVirginMap, offVirginMap, flameRect[1], flameRect[0], srcCopy, nil);
  420.         CopyBits(offLoadMap, offVirginMap, flameRect[0], flameRect[1], srcCopy, nil);
  421.  
  422. {copy all neccesary background rects to the load map}
  423.         with theEye do
  424.             if (mode > 0) then
  425.                 begin
  426.                     UnionRect(oldDest, dest, wholeRect);
  427.                     CopyBits(offVirginMap, offLoadMap, wholeRect, wholeRect, srcCopy, nil);
  428.                 end;
  429.  
  430.         for index := 1 to numberOfEnemies do
  431.             with theEnemies[index] do
  432.                 begin
  433.                     UnionRect(oldDest, dest, wholeRect);
  434.                     CopyBits(offVirginMap, offLoadMap, wholeRect, wholeRect, srcCopy, nil);
  435.                     oldDest := dest;
  436.                 end;
  437.  
  438. {copy the beasts through their masks onto the load map}
  439.         for index := 1 to numberOfEnemies do
  440.             with theEnemies[index] do
  441.                 begin
  442.                     if (mode < 6) then
  443.                         begin
  444.                             if (mode < 0) then
  445.                                 begin
  446.                                     tempSrc := eggRects[0];
  447.                                     tempMask := eggRects[1];
  448.                                     tempSrc.bottom := tempSrc.top + (dest.bottom - dest.top);
  449.                                     tempMask.bottom := tempMask.top + (dest.bottom - dest.top);
  450.                                     CopyMask(offPlayerMap, offPlayerMap, offLoadMap, tempSrc, tempMask, dest);
  451.                                 end
  452.                             else
  453.                                 CopyMask(offEnemyMap, offEnemyMap, offLoadMap, enemyRects[otherMode, mode, facing, 0], enemyRects[otherMode, mode, facing, 1], dest)
  454.                         end
  455.                     else
  456.                         begin
  457.                             otherRect := enemyRects[otherMode, 1, facing, source];
  458.                             otherRect.bottom := otherRect.top + (dest.bottom - dest.top);
  459.                             otherMask := enemyRects[otherMode, 1, facing, mask];
  460.                             otherMask.bottom := otherMask.top + (dest.bottom - dest.top);
  461.                             CopyMask(offEnemyMap, offEnemyMap, offLoadMap, otherRect, otherMask, dest);
  462.                         end;
  463.                 end;
  464.         CopyBits(offVirginMap, mainWndo^.portBits, flameRect[0], flameRect[0], srcCopy, nil);
  465.         CopyBits(offVirginMap, mainWndo^.portBits, flameRect[1], flameRect[1], srcCopy, nil);
  466.         {copy the sum bitmaps to the screen}
  467.         for index := 1 to numberOfEnemies do
  468.             with theEnemies[index] do
  469.                 CopyBits(offLoadMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, playRgn);
  470.  
  471.         with theEye do
  472.             if (mode > 0) then
  473.                 begin
  474.                     CopyMask(offPlayerMap, offPlayerMap, offLoadMap, eyeRects[otherMode], eyeRects[otherMode + 5], dest);
  475.                     CopyBits(offLoadMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, playRgn);
  476.                     oldDest := dest;
  477.                 end;
  478.     end;
  479.  
  480. {=================================}
  481.  
  482.     procedure RedoTheBackground;
  483.         var
  484.             tempRect, anotherRect: Rect;
  485.             Pic_Handle: PicHandle;
  486.     begin
  487.         SetPort(offVirginPort);        {Set the port to my window}
  488.         Pic_Handle := GetPicture(1);    {Get Picture into memory}
  489.         SetRect(tempRect, 0, 0, 512, 342);        {left,top,right,bottom}
  490.         if (Pic_Handle <> nil) then    {Only use handle if it is valid}
  491.             begin
  492.                 ClipRect(tempRect);        {Clip picture to this rectangle}
  493.                 HLock(Handle(Pic_Handle));    {Lock the handle before using it}
  494.                 tempRect.Right := tempRect.Left + (Pic_Handle^^.picFrame.Right - Pic_Handle^^.picFrame.Left);
  495.                 tempRect.Bottom := tempRect.Top + (Pic_Handle^^.picFrame.Bottom - Pic_Handle^^.picFrame.Top);
  496.                 HUnLock(Handle(Pic_Handle));{Unlock the picture again}
  497.             end;
  498.         if (Pic_Handle <> nil) then    {Only use handle if it is valid}
  499.             DrawPicture(Pic_Handle, tempRect);{Draw this picture}
  500.         ReleaseResource(Handle(Pic_Handle));
  501.         if (numberOfStones > 2) then
  502.             begin
  503.                 tempRect := upperTombRect1;
  504.                 OffsetRect(tempRect, tombRects[3].right - tempRect.right, tombRects[3].top - tempRect.top);
  505.                 CopyBits(offPlayerMap, offVirginMap, upperTombRect1, tempRect, srcCopy, nil);
  506.                 tempRect := upperTombRect2;
  507.                 OffsetRect(tempRect, tombRects[4].left - tempRect.left, tombRects[4].top - tempRect.top);
  508.                 CopyBits(offPlayerMap, offVirginMap, upperTombRect2, tempRect, srcCopy, nil);
  509.             end;
  510.         if ((numberOfStones > 4) and (levelOn <> 3)) then
  511.             begin
  512.                 CopyBits(offEnemyMap, offVirginMap, littleTombRect, tombRects[5], srcCopy, nil);
  513.             end;
  514.         if (levelOn < 3) then
  515.             begin
  516.                 SetRect(tempRect, 166, 316, 346, 332);
  517.                 anotherRect := tempRect;
  518.                 anotherRect.left := anotherRect.left - 180;
  519.                 anotherRect.right := anotherRect.right - 180;
  520.                 CopyBits(offVirginMap, offVirginMap, tempRect, anotherRect, srcCopy, playRgn);
  521.                 anotherRect.left := anotherRect.left + 180 + 180;
  522.                 anotherRect.right := anotherRect.right + 180 + 180;
  523.                 CopyBits(offVirginMap, offVirginMap, tempRect, anotherRect, srcCopy, playRgn);
  524.             end;
  525.  
  526.         SetRect(tempRect, 0, 0, 512, 342);
  527.         CopyBits(offVirginMap, mainWndo^.portBits, tempRect, tempRect, srcCopy, nil);
  528.     end;
  529.  
  530. {=================================}
  531.  
  532.     procedure ShowScore;
  533.         var
  534.             tempString: Str255;
  535.     begin
  536.         CopyBits(offEnemyMap, mainWndo^.portBits, scoreGrabRect, scoreDropRect, srcCopy, nil);
  537.         SetPort(mainWndo);
  538.         PenNormal;
  539.         MoveTo(261, 179);
  540.         TextFont(0);
  541.         TextSize(12);
  542.         NumToString(score, tempString);
  543.         DrawString(tempString);
  544.     end;
  545.  
  546. {=================================}
  547.  
  548.     procedure DoTheHoopla;
  549.         var
  550.             index, index2, index3, tempNum: Integer;
  551.             dummyLong: LongInt;
  552.             theseAhnks: array[1..24] of Rect;
  553.             ahnkModes: array[1..24] of Integer;
  554.     begin
  555.         ShowScore;
  556.         tempNum := mortals;
  557.         if (tempNum > 24) then
  558.             tempNum := 24;
  559.         for index := 1 to tempNum do
  560.             begin
  561.                 SetRect(theseAhnks[index], (239 - (mortals * 10) + (index * 20)), 200, (254 - (mortals * 10) + (index * 20)), 224);
  562.                 CopyMask(offPlayerMap, offPlayerMap, mainWndo^.portBits, ankRects[0, 0], ankRects[0, 1], theseAhnks[index]);
  563.                 DoTheSound('flip.snd', TRUE);
  564.                 ahnkModes[index] := 0;
  565.                 for index2 := 1 to 30 do
  566.                     for index3 := 1 to index do
  567.                         begin
  568.                             ahnkModes[index3] := ahnkModes[index3] + 1;
  569.                             if (ahnkModes[index3] > 15) then
  570.                                 ahnkModes[index3] := 0;
  571.                             CopyBits(offVirginMap, offLoadMap, theseAhnks[index3], theseAhnks[index3], srcCopy, nil);
  572.                             CopyMask(offPlayerMap, offPlayerMap, offLoadMap, ankRects[ahnkModes[index3], 0], ankRects[ahnkModes[index3], 1], theseAhnks[index3]);
  573.                             CopyBits(offLoadMap, mainWndo^.portBits, theseAhnks[index3], theseAhnks[index3], srcCopy, nil);
  574.                         end;
  575.             end;
  576.         for index2 := 1 to 50 do
  577.             for index3 := 1 to tempNum do
  578.                 begin
  579.                     if (ahnkModes[index3] <> 0) then
  580.                         ahnkModes[index3] := ahnkModes[index3] + 1;
  581.                     if (ahnkModes[index3] > 15) then
  582.                         begin
  583.                             DoTheSound('ahnk.snd', TRUE);
  584.                             ahnkModes[index3] := 0;
  585.                         end;
  586.                     CopyBits(offVirginMap, offLoadMap, theseAhnks[index3], theseAhnks[index3], srcCopy, nil);
  587.                     CopyMask(offPlayerMap, offPlayerMap, offLoadMap, ankRects[ahnkModes[index3], 0], ankRects[ahnkModes[index3], 1], theseAhnks[index3]);
  588.                     CopyBits(offLoadMap, mainWndo^.portBits, theseAhnks[index3], theseAhnks[index3], srcCopy, nil);
  589.                 end;
  590.         for index3 := 1 to tempNum do
  591.             CopyBits(offVirginMap, mainWndo^.portBits, theseAhnks[index3], theseAhnks[index3], srcCopy, nil);
  592.     end;
  593.  
  594. {=================================}
  595.  
  596.     procedure CheckExtraMortal;
  597.     begin
  598.         if (score > nextMortal) then
  599.             begin
  600.                 DoTheSound('bonus.snd', FALSE);    {You got an extra player!}
  601.                 mortals := mortals + 1;
  602.                 nextMortal := nextMortal + 20000;
  603.             end;
  604.     end;
  605.  
  606. {=================================}
  607.  
  608.     procedure ReDrawHiScores;
  609.         var
  610.             index: Integer;
  611.             dummyLong: LongInt;
  612.             tempRect: Rect;
  613.             dummyString: Str255;
  614.     begin
  615.         SetPort(offLoadPort);
  616.         PenNormal;
  617.         SetRect(tempRect, 170, 100, 347, 280);
  618.         FillRect(tempRect, black);
  619.         TextFont(0);
  620.         TextSize(12);
  621.         TextMode(srcXOr);
  622.         MoveTo(184, 125);
  623.         DrawString('Glypha 3.0 High Scores');
  624.         TextFont(1);
  625.         TextSize(9);
  626.         for index := 1 to 10 do    {Now we're going to loop through all the scores    }
  627.             begin
  628.                 MoveTo(185, index * 14 + 129);            {Moving the pen down each time    }
  629.                 DrawString(hiStrings[index]);                {Draw the name of person        }
  630.                 MoveTo(290, index * 14 + 129);            {Move pen over to the right        }
  631.                 NumToString(hiScores[index], dummyString);
  632.                 DrawString(dummyString);                        {And draw their score            }
  633.             end;                            {Copy the screen to the virgin port for updates    }
  634.         tempRect.top := tempRect.bottom;
  635.         for index := 1 to 86 do
  636.             begin
  637.                 tempRect.top := tempRect.top - 2;
  638.                 CopyBits(offLoadMap, mainWndo^.portBits, tempRect, tempRect, srcCopy, nil);
  639.             end;
  640.  
  641.         CopyBits(mainWndo^.portBits, offVirginMap, mainWndo^.portRect, mainWndo^.portRect, srcCopy, nil);
  642.     end;
  643.  
  644. {=================================}
  645.  
  646.     procedure ReadInScores;
  647.         type
  648.             scoreHandle = ^scorePtr;
  649.             scorePtr = ^score;
  650.             score = record
  651.                     data: array[0..9] of LongInt;
  652.                 end;
  653.  
  654.             nameHandle = ^namePtr;
  655.             namePtr = ^name;
  656.             name = record
  657.                     data: array[0..9, 0..14] of Char;
  658.                 end;
  659.  
  660.             prefHandle = ^prefPtr;
  661.             prefPtr = ^pref;
  662.             pref = record
  663.                     data: array[0..31] of Char;
  664.                 end;
  665.  
  666.         var
  667.             index, index2: Integer;
  668.             dummyStr: Str255;
  669.             theScores: scoreHandle;
  670.             theNames: nameHandle;
  671.             thePrefs: prefHandle;
  672.  
  673.     begin
  674.         theScores := scoreHandle(NewHandle(SIZEOF(score)));
  675.         MoveHHi(Handle(theScores));
  676.         HLock(Handle(theScores));
  677.         Handle(theScores) := GetResource('scrs', 128);
  678.         for index := 0 to 9 do
  679.             hiScores[index + 1] := theScores^^.data[index];
  680.         ReleaseResource(Handle(theScores));
  681.         HUnlock(Handle(theScores));
  682.         DisposHandle(Handle(theScores));
  683.  
  684.         theNames := nameHandle(NewHandle(SIZEOF(name)));
  685.         MoveHHi(Handle(theNames));
  686.         HLock(Handle(theNames));
  687.         Handle(theNames) := GetResource('name', 128);
  688.         for index := 0 to 9 do
  689.             begin
  690.                 dummyStr := '';
  691.                 for index2 := 0 to 14 do
  692.                     dummyStr := CONCAT(dummyStr, theNames^^.data[index, index2]);
  693.                 hiStrings[index + 1] := dummyStr;
  694.             end;
  695.         ReleaseResource(Handle(theNames));
  696.         HUnlock(Handle(theNames));
  697.         DisposHandle(Handle(theNames));
  698.  
  699.         thePrefs := prefHandle(NewHandle(SIZEOF(pref)));
  700.         MoveHHi(Handle(thePrefs));
  701.         HLock(Handle(thePrefs));
  702.         Handle(thePrefs) := GetResource('pref', 128);
  703.  
  704.         if (thePrefs^^.data[0] = 'M') then
  705.             keyboardControl := FALSE
  706.         else
  707.             keyboardControl := TRUE;
  708.         if (thePrefs^^.data[1] = 'S') then
  709.             soundOn := TRUE
  710.         else
  711.             soundOn := FALSE;
  712.         if (inhibitSound) then
  713.             soundOn := FALSE;
  714.  
  715.         case thePrefs^^.data[2] of
  716.             'L': 
  717.                 delayFor := slowest;
  718.             'S': 
  719.                 delayFor := slow;
  720.             'F': 
  721.                 delayFor := fast;
  722.             'A': 
  723.                 delayFor := fastest;
  724.             otherwise
  725.                 begin
  726.                 end;
  727.         end;
  728.  
  729.         nameUsing := '';
  730.         for index := 1 to 15 do
  731.             nameUsing := CONCAT(nameUsing, thePrefs^^.data[index + 16]);
  732.  
  733.         ReleaseResource(Handle(thePrefs));
  734.         HUnlock(Handle(thePrefs));
  735.         DisposHandle(Handle(thePrefs));
  736.  
  737.         scoresChanged := FALSE;
  738.     end;
  739.  
  740. {=================================}
  741.  
  742.     procedure WriteOutScores;
  743.         type
  744.             scoreHandle = ^scorePtr;
  745.             scorePtr = ^score;
  746.             score = record
  747.                     data: array[0..9] of LongInt;
  748.                 end;
  749.  
  750.             nameHandle = ^namePtr;
  751.             namePtr = ^name;
  752.             name = record
  753.                     data: array[0..9, 0..14] of Char;
  754.                 end;
  755.  
  756.             prefHandle = ^prefPtr;
  757.             prefPtr = ^pref;
  758.             pref = record
  759.                     data: array[0..31] of Char;
  760.                 end;
  761.  
  762.         var
  763.             index, index2: Integer;
  764.             dummyStr: Str255;
  765.             theScores: scoreHandle;
  766.             theNames: nameHandle;
  767.             thePrefs: prefHandle;
  768.  
  769.     begin
  770.         thePrefs := prefHandle(NewHandle(SIZEOF(pref)));
  771.         HLock(Handle(thePrefs));
  772.         Handle(thePrefs) := GetResource('pref', 128);
  773.         if (keyboardControl) then
  774.             thePrefs^^.data[0] := 'K'
  775.         else
  776.             thePrefs^^.data[0] := 'M';
  777.         if (soundOn) then
  778.             thePrefs^^.data[1] := 'S'
  779.         else
  780.             thePrefs^^.data[1] := 'N';
  781.  
  782.         case delayFor of
  783.             slowest: 
  784.                 thePrefs^^.data[2] := 'L';
  785.             slow: 
  786.                 thePrefs^^.data[2] := 'S';
  787.             fast: 
  788.                 thePrefs^^.data[2] := 'F';
  789.             fastest: 
  790.                 thePrefs^^.data[2] := 'A';
  791.             otherwise
  792.                 begin
  793.                 end;
  794.         end;
  795.  
  796.         for index := 1 to 15 do
  797.             thePrefs^^.data[index + 16] := COPY(nameUsing, index, 1);
  798.         ChangedResource(Handle(thePrefs));
  799.         WriteResource(Handle(thePrefs));
  800.         ReleaseResource(Handle(thePrefs));
  801.         HUnlock(Handle(thePrefs));
  802.         DisposHandle(Handle(thePrefs));
  803.  
  804.         if (scoresChanged) then
  805.             begin
  806.                 theScores := scoreHandle(NewHandle(SIZEOF(score)));
  807.                 MoveHHi(Handle(theScores));
  808.                 HLock(Handle(theScores));
  809.                 Handle(theScores) := GetResource('scrs', 128);
  810.                 for index := 0 to 9 do
  811.                     theScores^^.data[index] := hiScores[index + 1];
  812.                 ChangedResource(Handle(theScores));
  813.                 WriteResource(Handle(theScores));
  814.                 ReleaseResource(Handle(theScores));
  815.                 HUnlock(Handle(theScores));
  816.                 DisposHandle(Handle(theScores));
  817.  
  818.                 theNames := nameHandle(NewHandle(SIZEOF(name)));
  819.                 HLock(Handle(theNames));
  820.                 Handle(theNames) := GetResource('name', 128);
  821.                 for index := 0 to 9 do
  822.                     for index2 := 0 to 14 do
  823.                         theNames^^.data[index, index2] := COPY(hiStrings[index + 1], index2 + 1, 1);
  824.                 ChangedResource(Handle(theNames));
  825.                 WriteResource(Handle(theNames));
  826.                 ReleaseResource(Handle(theNames));
  827.                 HUnlock(Handle(theNames));
  828.                 DisposHandle(Handle(theNames));
  829.             end;
  830.     end;
  831.  
  832. {=================================}
  833.  
  834.     procedure FinalScore;
  835.         var
  836.             index, ranking: Integer;
  837.     begin
  838.         FlushEvents(everyEvent, 0);                                    {Clear all the keystrokes    }
  839.         if (score > hiScores[10]) and (mortalsStart = defaultNum) then        {Is it a high score?            }
  840.             begin
  841.                 scoresChanged := TRUE;                        {Mark scores as changed            }
  842.                 DoTheSound('bonus.snd', FALSE);        {Play the bonus sound.            }
  843.                 ranking := 10;                                        {And sort through the high    }
  844.                 for index := 9 downto 1 do                {scores to find the players    }
  845.                     begin                                                        {ranking.                                        }
  846.                         if (score > hiScores[index]) then
  847.                             ranking := index;
  848.                     end;
  849.                 for index := 10 downto ranking + 1 do
  850.                     begin
  851.                         hiScores[index] := hiScores[index - 1];        {Move everyone's score}
  852.                         hiStrings[index] := hiStrings[index - 1];    {down the list.                }
  853.                     end;
  854.                 hiScores[ranking] := score;
  855.                 SetPort(mainWndo);
  856.                 WhosHiScore(nameUsing);
  857.                 hiStrings[ranking] := nameUsing;
  858.             end;
  859.     end;
  860.  
  861. {=================================}
  862.  
  863.     procedure DoHelpScreen;
  864.         var
  865.             index: Integer;
  866.             tempRect, dropRect: Rect;
  867.             Pic_Handle: PicHandle;
  868.             theEvent: EventRecord;
  869.     begin
  870.         SetPort(offLoadPort);
  871.         Pic_Handle := GetPicture(2000);
  872.         SetRect(tempRect, 0, 0, 360, 338);
  873.         if (Pic_Handle <> nil) then
  874.             begin
  875.                 ClipRect(tempRect);
  876.                 HLock(Handle(Pic_Handle));
  877.                 tempRect.Right := tempRect.Left + (Pic_Handle^^.picFrame.Right - Pic_Handle^^.picFrame.Left);
  878.                 tempRect.Bottom := tempRect.Top + (Pic_Handle^^.picFrame.Bottom - Pic_Handle^^.picFrame.Top);
  879.                 HUnLock(Handle(Pic_Handle));
  880.             end;
  881.         if (Pic_Handle <> nil) then
  882.             DrawPicture(Pic_Handle, tempRect);
  883.         ReleaseResource(Handle(Pic_Handle));
  884.         SetRect(tempRect, 0, 0, 1023, 1023);
  885.         ClipRect(tempRect);
  886.         SetRect(dropRect, 168, 278, 348, 278);
  887.         SetRect(tempRect, 0, 169, 180, 169);
  888.         for index := 1 to 169 do
  889.             begin
  890.                 dropRect.top := dropRect.top - 1;
  891.                 tempRect.top := tempRect.top - 1;
  892.                 CopyBits(offLoadMap, mainWndo^.portBits, tempRect, dropRect, srcCopy, nil);
  893.             end;
  894.         SetRect(dropRect, 168, 109, 348, 278);
  895.         SetRect(tempRect, 0, 0, 180, 169);
  896.         FlushEvents(everyEvent, 0);
  897.         SetEventMask(playMask);
  898.         repeat
  899.         until (GetNextEvent(playMask, theEvent));
  900.         for index := 1 to 180 do
  901.             begin
  902.                 tempRect.left := tempRect.left + 1;
  903.                 tempRect.right := tempRect.right + 1;
  904.                 CopyBits(offLoadMap, mainWndo^.portBits, tempRect, dropRect, srcCopy, nil);
  905.             end;
  906.         FlushEvents(everyEvent, 0);
  907.         repeat
  908.         until (GetNextEvent(playMask, theEvent));
  909.         for index := 1 to 169 do
  910.             begin
  911.                 tempRect.top := tempRect.top + 1;
  912.                 tempRect.bottom := tempRect.bottom + 1;
  913.                 CopyBits(offLoadMap, mainWndo^.portBits, tempRect, dropRect, srcCopy, nil);
  914.             end;
  915.         FlushEvents(everyEvent, 0);
  916.         repeat
  917.         until (GetNextEvent(playMask, theEvent));
  918.         for index := 1 to 180 do
  919.             begin
  920.                 tempRect.left := tempRect.left - 1;
  921.                 tempRect.right := tempRect.right - 1;
  922.                 CopyBits(offLoadMap, mainWndo^.portBits, tempRect, dropRect, srcCopy, nil);
  923.             end;
  924.         FlushEvents(everyEvent, 0);
  925.         repeat
  926.         until (GetNextEvent(playMask, theEvent));
  927.         SetEventMask(EveryEvent);
  928.         RedrawHiScores;
  929.     end;
  930.  
  931. {=================================}
  932.  
  933.     procedure FlushTheScores;
  934.         var
  935.             index: Integer;
  936.     begin
  937.         for index := 1 to 10 do
  938.             begin
  939.                 hiScores[index] := 0;
  940.                 hiStrings[index] := 'Play Me .......';
  941.             end;
  942.         scoresChanged := TRUE;
  943.         RedrawHiScores;
  944.     end;
  945.  
  946. {=================================}
  947.  
  948. end.